package wiki.kaizen.cloud.plugin.spring;



import com.alibaba.fastjson.JSON;
import lombok.Getter;
import lombok.Setter;

import java.io.Serializable;
import java.util.Map;

/**
* 返回数据
*  code 状态码
*  msg 消息;
*  data 重要数据
*  gift 附赠数据 一般情况下无需使用
*
* @author xeepoo
* */

@Getter
@Setter
public class R implements Serializable {

    private static final long serialVersionUID = 1L;
    private Integer code;
    private String msg;
    private Object data;
    private R(){};
    private R(Integer code, String msg, Object data) {
        this.code = code;
        this.msg = msg;
        this.data = data;
    }
    public  boolean isSuccess(){
        return this.code != null && this.code == HttpStatusCode.SUCCESS;
    }



    public static R.RBuilder ok(){
        return R.builder().msg("success").code(HttpStatusCode.SUCCESS);

    }

    public static R.RBuilder ok(String msg){
        return R.builder().code(HttpStatusCode.SUCCESS).msg(msg);

    }

    public static R.RBuilder error(String msg){
        return R.builder().code(500).msg(msg);
    }

    public static  R.RBuilder error(Integer code,String msg){
        return R.builder().code(code).msg(msg);
    }

    private static R.RBuilder builder(){
        return  new R.RBuilder();
    }

	/**
	 * 默认回滚事务
	 */
	public <T> SimpleTuber<T> toSimpleTuber(){
        return toSimpleTuber(true);
    }

	/**
	 *
	 * @param rollback 是否回滚事务
	 */
	public <T> SimpleTuber<T> toSimpleTuber(boolean rollback){
		if (isSuccess()){
			return SimpleTuber.data((T)data);
		}

		return SimpleTuber.error(code,msg,rollback);
	}

    /*
    * RBuider
    * */
    public static class RBuilder{
        private Integer code;
        private String msg;
        private Object data;


        public R.RBuilder code(Integer code){
            this.code = code;
            return this;
        }

        public R.RBuilder msg(String msg){
            this.msg = msg;
            return this;
        }
        public R.RBuilder data(SimpleTuber tuber){
            if (tuber == null){
                return R.ok();
            }

            if (tuber.getData() != null){
                RBuilder ok = R.ok();
                ok.data = tuber.getData();
                return ok;
            }

            Map<String, Object> tuberMap;
            if (( tuberMap= tuber.get())==null){
                return R.ok();
            }

            if (tuberMap.containsKey("code")){
                this.code = Integer.valueOf(
                    String.valueOf(
                        tuberMap.get("code")
                    )
                );
                tuberMap.remove("code");
            }
            if (tuberMap.containsKey("msg")){
                this.msg = String.valueOf(
                    tuberMap.get("msg")
                );
                tuberMap.remove("msg");
            }
            this.data = tuberMap;
            return this;
        }
        public R.RBuilder data(Object data){
            this.data = data;
            return this;
        }

        public R build(){
            return new R(code,msg,data);
        }
    }

    public Integer getCode() {
        return code;
    }

    public String getMsg() {
        return msg;
    }

    public Object getData() {
        return data;
    }

    @Override
    public String toString() {
        return JSON.toJSONString(this);
    }
}
